package com.wondersgroup.app.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wondersgroup.core.frame.CommonStatusResult;
import com.wondersgroup.core.frame.TraceException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

/**
 * 全局异常拦截处理类
 * @author wanglei
 */
public class DefaultHandlerExceptionResolver implements HandlerExceptionResolver{

    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHandlerExceptionResolver.class);
    private ObjectMapper objectMapper;

    private String defaultErrorView = "error";

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        String errorCode = null;
        String errorMessage = null;
        String exceptionInfo = "";
        CommonStatusResult result = null;
        if (e != null) {
            if (e instanceof TraceException) {
                errorCode = ((TraceException) e).getErrorCode();
                errorMessage = ((TraceException) e).getMessage();
                if (errorCode == null) {
                    errorCode = ((TraceException) e).getMessage();
                }
                if(errorMessage == null || errorMessage.isEmpty()){
                    result = CommonStatusResult.fail(errorCode, null);
                }else{
                    result = CommonStatusResult.create(CommonStatusResult.STATUS_FAIL, errorCode, errorMessage, "", null);
                }
            } else {
                exceptionInfo = e.getMessage();
                result = CommonStatusResult.error(exceptionInfo, exceptionInfo, null);
            }
        }

        if (result != null) {
            errorCode = result.getMessageCode();
            errorMessage = result.getMessage();
            exceptionInfo = result.getException();
        }
        LOGGER.error("Error: [" + (errorCode != null ? errorCode : "") + "] Message: " + (errorMessage != null ? errorMessage : ""));
        if (e != null) {
            LOGGER.error("Exception: ", e);
        }

        String error = null;
        try {
            error = objectMapper.writeValueAsString(result);
        } catch (JsonProcessingException ex) {
            error = "{\"status\":1,\"messageCode\":\"" + (errorCode != null ? errorCode : "") + "\",\"message\":\"" + 
                    (errorMessage != null ? errorMessage : "") + "\",\"exception\":\""+ (exceptionInfo != null ? exceptionInfo : "") +"\",\"body\":null}";
        }

        ModelAndView modelAndView = new ModelAndView(defaultErrorView);
        modelAndView.addObject("error", error);

        return modelAndView;
    }

    public ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    public String getDefaultErrorView() {
        return defaultErrorView;
    }

    public void setDefaultErrorView(String defaultErrorView) {
        this.defaultErrorView = defaultErrorView;
    }
    
}
